//
//  ContentViewController.swift
//  SpeechAnalyzerDemo
//
//  UIKit 版本的主页控制器，用于替换原有 SwiftUI 界面。
//

import UIKit
import Combine

final class ContentViewController: UIViewController {

    private let manager: SpeechAnalyzeManager
    private var cancellables = Set<AnyCancellable>()

    private var supportedLocales: [Locale] = []
    private var selectedLocale: Locale {
        didSet {
            updateLocalePresentation()
        }
    }

    // UI 组件
    private let scrollView = UIScrollView()
    private let contentStack = UIStackView()
    private let instructionsLabel = UILabel()
    private let localeValueField = UITextField()
    private let localePicker = UIPickerView()
    private let applyButton = UIButton(type: .system)
    private let fileDemoButton = UIButton(type: .system)
    private let realTimeDemoButton = UIButton(type: .system)
    private let loadingOverlay = UIVisualEffectView(effect: UIBlurEffect(style: .systemChromeMaterial))
    private let loadingIndicator = UIActivityIndicatorView(style: .large)

    init(manager: SpeechAnalyzeManager) {
        self.manager = manager
        self.selectedLocale = manager.locale
        super.init(nibName: nil, bundle: nil)
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBackground
        title = "Speech To Text"

        setupLayout()
        configureUI()
        bindManager()
        fetchSupportedLocales()
    }
}

// MARK: - 界面构建
private extension ContentViewController {
    func setupLayout() {
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        contentStack.translatesAutoresizingMaskIntoConstraints = false
        loadingOverlay.translatesAutoresizingMaskIntoConstraints = false
        loadingIndicator.translatesAutoresizingMaskIntoConstraints = false

        contentStack.axis = .vertical
        contentStack.spacing = 24

        view.addSubview(scrollView)
        scrollView.addSubview(contentStack)
        view.addSubview(loadingOverlay)
        loadingOverlay.contentView.addSubview(loadingIndicator)

        NSLayoutConstraint.activate([
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),

            contentStack.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: 20),
            contentStack.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: -20),
            contentStack.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 24),
            contentStack.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
            contentStack.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor, constant: -40),

            loadingOverlay.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            loadingOverlay.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            loadingOverlay.topAnchor.constraint(equalTo: view.topAnchor),
            loadingOverlay.bottomAnchor.constraint(equalTo: view.bottomAnchor),

            loadingIndicator.centerXAnchor.constraint(equalTo: loadingOverlay.centerXAnchor),
            loadingIndicator.centerYAnchor.constraint(equalTo: loadingOverlay.centerYAnchor)
        ])
    }

    func configureUI() {
        instructionsLabel.numberOfLines = 0
        instructionsLabel.text = "With Speech Analyzer"
        instructionsLabel.font = .preferredFont(forTextStyle: .headline)

        let localeContainer = UIStackView()
        localeContainer.axis = .vertical
        localeContainer.spacing = 8

        let localeTitleLabel = UILabel()
        localeTitleLabel.text = "Locale" + "(" + self.selectedLocale.description + ")"
        localeTitleLabel.font = .preferredFont(forTextStyle: .subheadline)
        localeTitleLabel.textColor = .secondaryLabel

        localeValueField.borderStyle = .roundedRect
        localeValueField.inputView = localePicker
        localeValueField.tintColor = .clear // 隐藏输入光标
        localeValueField.delegate = self

        localePicker.dataSource = self
        localePicker.delegate = self

        applyButton.setTitle("Apply Change", for: .normal)
        applyButton.setTitleColor(.white, for: .normal)
        applyButton.setTitleColor(.white.withAlphaComponent(0.4), for: .disabled)
        applyButton.backgroundColor = .systemBlue
        applyButton.layer.cornerRadius = 8
        applyButton.heightAnchor.constraint(equalToConstant: 44).isActive = true
        applyButton.addTarget(self, action: #selector(applyLocaleChange), for: .touchUpInside)

        fileDemoButton.setTitle("Transcribe From File", for: .normal)
        fileDemoButton.contentHorizontalAlignment = .leading
        fileDemoButton.addTarget(self, action: #selector(openFileTranscription), for: .touchUpInside)

        realTimeDemoButton.setTitle("Real Time Transcription", for: .normal)
        realTimeDemoButton.contentHorizontalAlignment = .leading
        realTimeDemoButton.addTarget(self, action: #selector(openRealTimeTranscription), for: .touchUpInside)

        localeContainer.addArrangedSubview(localeTitleLabel)
        localeContainer.addArrangedSubview(localeValueField)

        contentStack.addArrangedSubview(instructionsLabel)
        contentStack.addArrangedSubview(localeContainer)
        contentStack.addArrangedSubview(applyButton)
        contentStack.addArrangedSubview(makeDivider())
        contentStack.addArrangedSubview(makeSection(title: "Transcribe From File", detail: "Select a file, and transcribe the contents.", button: fileDemoButton))
        contentStack.addArrangedSubview(makeDivider())
        contentStack.addArrangedSubview(makeSection(title: "Real Time Transcription", detail: "Capture the input, and transcribe in real time.", button: realTimeDemoButton))

        loadingOverlay.isHidden = true
        loadingIndicator.hidesWhenStopped = true
    }

    func makeDivider() -> UIView {
        let divider = UIView()
        divider.backgroundColor = .separator
        divider.translatesAutoresizingMaskIntoConstraints = false
        divider.heightAnchor.constraint(equalToConstant: 1 / UIScreen.main.scale).isActive = true
        return divider
    }

    func makeSection(title: String, detail: String, button: UIButton) -> UIView {
        let container = UIStackView()
        container.axis = .vertical
        container.spacing = 8

        let titleLabel = UILabel()
        titleLabel.text = title
        titleLabel.font = .preferredFont(forTextStyle: .headline)

        let detailLabel = UILabel()
        detailLabel.text = detail
        detailLabel.font = .preferredFont(forTextStyle: .subheadline)
        detailLabel.textColor = .secondaryLabel
        detailLabel.numberOfLines = 0

        container.addArrangedSubview(titleLabel)
        container.addArrangedSubview(detailLabel)
        container.addArrangedSubview(button)

        return container
    }
}

// MARK: - 数据绑定
private extension ContentViewController {
    func bindManager() {
        manager.$locale
            .receive(on: RunLoop.main)
            .sink { [weak self] locale in
                guard let self else { return }
                self.selectedLocale = locale
            }
            .store(in: &cancellables)

        manager.$isSettingUp
            .receive(on: RunLoop.main)
            .sink { [weak self] isSettingUp in
                self?.setLoading(isSettingUp)
            }
            .store(in: &cancellables)

        manager.$showError
            .receive(on: RunLoop.main)
            .sink { [weak self] showError in
                guard
                    showError,
                    let self,
                    let error = self.manager.error
                else { return }
                self.presentError(message: error.message)
            }
            .store(in: &cancellables)
    }

    func setLoading(_ loading: Bool) {
        loadingOverlay.isHidden = !loading
        if loading {
            loadingIndicator.startAnimating()
        } else {
            loadingIndicator.stopAnimating()
        }
        updateApplyButtonState()
    }
}

// MARK: - 语言支持
private extension ContentViewController {
    
    func fetchSupportedLocales() {
        Task { [weak self] in
            guard let self else { return }
            let locales = await Transcriber.supportedLocales.map(\.0)
            await MainActor.run {
                self.supportedLocales = locales
                self.localePicker.reloadAllComponents()
                self.updateLocalePresentation()
            }
        }
    }

    func updateLocalePresentation() {
        let displayName = selectedLocale.localizedString(forIdentifier: selectedLocale.identifier) ?? selectedLocale.identifier
        localeValueField.text = displayName
        updateApplyButtonState()

        if let index = supportedLocales.firstIndex(where: { $0.identifier == selectedLocale.identifier }) {
            localePicker.selectRow(index, inComponent: 0, animated: true)
        }
    }

    func updateApplyButtonState() {
        let isBusy = manager.isSettingUp
        let disable = selectedLocale == manager.locale || isBusy
        applyButton.isEnabled = !disable
        applyButton.backgroundColor = disable ? .systemBlue.withAlphaComponent(0.4) : .systemBlue
    }
}

// MARK: - 提示框
private extension ContentViewController {
    
    func presentError(message: String) {
        let alert = UIAlertController(title: "Oops!", message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default) { [weak self] _ in
            self?.manager.showError = false
        })
        present(alert, animated: true, completion: nil)
    }
    
}

// MARK: - 用户操作
private extension ContentViewController {
    
    @objc func applyLocaleChange() {
        guard selectedLocale != manager.locale else { return }
        Task { [weak self] in
            guard let self else { return }
            do {
                try await self.manager.updateLocale(self.selectedLocale)
            } catch {
                self.manager.error = error
            }
        }
        //
        self.localeValueField.resignFirstResponder()
    }

    @objc func openFileTranscription() {
        let controller = FileTranscriptionViewController(manager: manager)
        navigationController?.pushViewController(controller, animated: true)
    }

    @objc func openRealTimeTranscription() {
        let controller = RealTimeTranscriptionViewController(manager: manager)
        navigationController?.pushViewController(controller, animated: true)
    }
}

// MARK: - UIPickerView 数据源与代理
extension ContentViewController: UIPickerViewDataSource, UIPickerViewDelegate {
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        supportedLocales.count
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        guard supportedLocales.indices.contains(row) else { return nil }
        let locale = supportedLocales[row]
        return locale.localizedString(forIdentifier: locale.identifier) ?? locale.identifier
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        guard supportedLocales.indices.contains(row) else { return }
        selectedLocale = supportedLocales[row]
    }
}

// MARK: - UITextFieldDelegate
extension ContentViewController: UITextFieldDelegate {
    
    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        if supportedLocales.isEmpty {
            fetchSupportedLocales()
        }
        return true
    }
}
